package ms.maplestory.boot.client;


import ms.maplestory.boot.Server;
import ms.maplestory.boot.client.character.Char;
import ms.maplestory.boot.connection.db.FileTimeConverter;
import ms.maplestory.boot.service.AccountService;
import ms.maplestory.boot.util.FileTime;
import lombok.Getter;
import lombok.Setter;
import ms.maplestory.boot.util.SpringUtil;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

@Getter
@Setter
@Entity
@Table(name = "accounts")
public class Account {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String name;
    private String password;
    private String pinCode;
    private String blockReason;

    @Convert(converter = FileTimeConverter.class)
    private FileTime blockExpireDate = FileTime.fromType(FileTime.Type.ZERO_TIME);

    private int latestConnectedWorld;

    @OneToMany(cascade = CascadeType.REMOVE, mappedBy = "account")
    private Set<User> users;

    @Transient
    private AccountService accountService;
    @Transient
    private Char currentChr;

    public Account() {
    }

    public Account(String name, String password) {
        this.name = name;
        this.password = password;
        this.users = new HashSet<>();
    }

    public AccountService getAccountService() {
        if (accountService == null) {
            accountService = SpringUtil.getBean("accountService", AccountService.class);
        }
        return accountService;
    }

    public void addUser(User user) {
        if (users == null) {
            this.users = new HashSet<>();
        }
        users.add(user);
    }

    public User getUserByWorldId(int worldId) {
        return users.stream()
                .filter(user -> user.getWorldId() == worldId)
                .findFirst().orElse(null);
    }

    public Set<Char> getAllChar() {
        return users.stream()
                .filter(user -> Server.getInstance().getWorldById(user.getWorldId()) != null)
                .filter(user -> user.getCharacters().size() != 0)
                .map(User::getCharacters)
                .flatMap(Set::stream)
                .collect(Collectors.toSet());
    }

    @Override
    public String toString() {
        return getClass().getName() + "{" +
                "(" + super.toString() +
                ")id=" + id +
                ", name=" + name +
                '}';
    }
}
